home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The X-Philes (2nd Revision)
/
The X-Philes Number 1 (1995).iso
/
xphiles
/
hp48_2
/
qsort
< prev
next >
Wrap
Text File
|
1995-03-31
|
4KB
|
91 lines
Article 1643 of comp.sys.handhelds:
From: alonzo@microsoft.UUCP (Alonzo GARIEPY)
Newsgroups: comp.sys.handhelds
Subject: More quicksort
Date: 27 Mar 90 23:03:27 GMT
Organization: Microsoft Corp., Redmond WA
Here is yet another incarnation of quicksort for the HP 48.
This variation differs in that only one copy of each element
exists while the sort is taking place. All objects are kept
on the stack (as references) so that the memory overhead is
about 5 nibbles per element (2500 bytes for a 1000 element
list). This is most helpful when you are sorting large objects
or are low on memory.
It is possible to use less memory by sorting in place, but that
would be extremely slow because of list handling. Sorting with
an array of references is a typical way to avoid the cost of
copying data during a sort.
In one test, this sort took about 24 minutes for a list of 500
random real number. It could be made faster by eliminating one
or both of the temporary variables. The sort could be made
faster by replacing the code, 1 i START n ROLLD NEXT, with a
single machine code command. I'll see what I can do.
QSORT
%%HP: T(3)A(D)F(.);
\<< LIST\-> QST \->LIST \>> @ sorts a list on the stack @
QST
%%HP: T(3)A(D)F(.);
\<< \-> n @ sorts a disassembled list on the stack @
\<< n 2 / ROLL n 3 + 2 n
START ROT 3 DUPN SWAP ROLLD > - NEXT
4 - \-> i
\<< n ROLLD
i IF DUP 1 > THEN QST END
IF DUP THEN 1 SWAP START n ROLLD NEXT i END
n SWAP 1 + - IF DUP 1 > THEN QST END DROP n
\>> \>> \>>
Sedgewick has shown that by quicksorting only until no sublist contains
greater than X elements (where X is 10 to 20) and then doing an insertion
sort on the resultant almost-sorted list, it is possible to get up to 20%
improvement in speed. Mark Adler brought this to my attention.
You can do that by changing the two instances of "1 >" in QST to "X >".
Then you need to perform an insertion sort on the partly sorted result of
QSORT. Since I haven't come up with a decent selection or insertion sort,
I prefer to leave the resolution at 1 and take my lumps. I invite others
to make these improvements.
The main speed considerations in sorting on the HP 28/48 are two.
1. It is much faster to manipulate objects on the stack than to use
lists. Moving stack objects is just a question of switching five
nibble pointers, but moving elements in a list involves copying
the objects themselves with all the requisite memory managment.
2. It is much faster to manipulate objects within global variables
than those in the heap. Each entry in the stack is a pointer to
an object. If the object was put on the stack by recalling or
disassembling (GET, GETI, OBJ->, LIST->, etc.) a global variable,
or by duplicating (DUP, OVER, etc.) an object that derives from
a global variable, it will not be subject to garbage collection.
Entries that result from calculation (PUT, ->LIST, +, SUB, etc.)
point to objects in the heap and must be garbage collected.
The program above will sort a list of 500 random numbers in 4 minutes
and 21 seconds(1). A list of 1000 random numbers took about 10 minutes
and 35 seconds(2). If you want to make sure you get this behaviour for
lists on the stack that may not derive from global variables, you can
modify QSORT to stash them in a temporary variable during the sort.
GQSORT
%%HP: T(3)A(D)F(.);
\<< 'QQQ' DUP PURGE STO QQQ LIST\-> QST 'QQQ' PURGE \->LIST \>>
Do not use GQSORT for big lists that are already in global variables
because storing a second copy in QQQ will make the sort slower.
Alonzo Gariepy
alonzo@microsoft
(1) On an HP 48 with 17 Kb of free memory (not including the list).
(2) On an HP 48 with 50 Kb of free memory (not including the list).